﻿using System;
using System.Reflection;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using WmsApp.Security;
using IServiceChannel = WmsApp.WmsService.IServiceChannel;

namespace WmsApp.Factory
{
    public class WmsServiceFactory
    {
        private static ChannelFactory<IServiceChannel> _factory;

        public static IServiceChannel GetServiceClient()
        {
            return CreateServiceChannel();
        }

        private static IServiceChannel CreateServiceChannel()
        {
            var proxy = GetChannelFactory().CreateChannel();

            if (UserSession.IsLogOn)
            {
                var scope = new OperationContextScope(proxy);
                var messageHeader = new MessageHeader<String>(UserSession.Token);
                var untypedHeader = messageHeader.GetUntypedHeader("token", "ns");
                OperationContext.Current.OutgoingMessageHeaders.Add(untypedHeader);
            }
            return proxy;
        }

        private static ChannelFactory<IServiceChannel> GetChannelFactory()
        {
            if (_factory == null)
            {
                _factory = new ChannelFactory<IServiceChannel>("BasicHttpBinding_IService");
                AttachServiceBehavior(_factory);
            }
            return _factory;
        }

        private static void AttachServiceBehavior(ChannelFactory<IServiceChannel> channelFactory)
        {
            //找到程序集的其中任何一个class，确定程序集
            var type = typeof (ClientRuntime);
            //实例化internal类，通过反射
            var instance =
                type.Assembly.CreateInstance("System.ServiceModel.Dispatcher.DataContractSerializerServiceBehavior",
                                             true,
                                             BindingFlags.CreateInstance | BindingFlags.Instance |
                                             BindingFlags.NonPublic, null, new object[] {false, Int32.MaxValue}, null,
                                             null);
            //转换成终结点的行为接口
            var behavior = instance as IEndpointBehavior;
            if (behavior != null)
            {
                //插入到通道工厂的终结点行为集合中
                channelFactory.Endpoint.Behaviors.Add(behavior);
            }
        }
    }
}